[IA64] Extend interfaces to use itir instead logps
authorAlex Williamson <alex.williamson@hp.com>
Mon, 30 Jul 2007 22:38:47 +0000 (16:38 -0600)
committerAlex Williamson <alex.williamson@hp.com>
Mon, 30 Jul 2007 22:38:47 +0000 (16:38 -0600)
Changed some interfaces to use cr.itir instead of only the logps part in
handling itc_i/itc_d and vhpt_insert.

Signed-off-by: Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
xen/arch/ia64/vmx/vmmu.c
xen/arch/ia64/vmx/vtlb.c
xen/arch/ia64/xen/faults.c
xen/arch/ia64/xen/mm.c
xen/arch/ia64/xen/vcpu.c
xen/arch/ia64/xen/vhpt.c
xen/include/asm-ia64/linux-xen/asm/processor.h
xen/include/asm-ia64/mm.h
xen/include/asm-ia64/vhpt.h

index 8c1b35735af60c279503e7e63f29f93f5b6d4058..9ddbc57b08b95517722fe270ac7c66a8526fac86 100644 (file)
@@ -232,10 +232,10 @@ void machine_tlb_insert(struct vcpu *v, thash_data_t *tlb)
 
     psr = ia64_clear_ic();
     if ( cl == ISIDE_TLB ) {
-        ia64_itc(1, mtlb.ifa, mtlb.page_flags, mtlb.ps);
+        ia64_itc(1, mtlb.ifa, mtlb.page_flags, IA64_ITIR_PS_KEY(mtlb.ps, 0));
     }
     else {
-        ia64_itc(2, mtlb.ifa, mtlb.page_flags, mtlb.ps);
+        ia64_itc(2, mtlb.ifa, mtlb.page_flags, IA64_ITIR_PS_KEY(mtlb.ps, 0));
     }
     ia64_set_psr(psr);
     ia64_srlz_i();
index 4261b0b9c2662ced650fb248a43e0497fc6d7e13..acc01128c2b420698b24d768cd67f2acd19ce5d3 100644 (file)
@@ -199,7 +199,7 @@ void thash_vhpt_insert(VCPU *v, u64 pte, u64 itir, u64 va, int type)
     } else {
         phy_pte  &= ~PAGE_FLAGS_RV_MASK;
         psr = ia64_clear_ic();
-        ia64_itc(type + 1, va, phy_pte, itir_ps(itir));
+        ia64_itc(type + 1, va, phy_pte, itir);
         ia64_set_psr(psr);
         ia64_srlz_i();
     }
@@ -562,7 +562,7 @@ int thash_purge_and_insert(VCPU *v, u64 pte, u64 itir, u64 ifa, int type)
             u64 psr;
             phy_pte  &= ~PAGE_FLAGS_RV_MASK;
             psr = ia64_clear_ic();
-            ia64_itc(type + 1, ifa, phy_pte, ps);
+            ia64_itc(type + 1, ifa, phy_pte, IA64_ITIR_PS_KEY(ps, 0));
             ia64_set_psr(psr);
             ia64_srlz_i();
             // ps < mrr.ps, this is not supported
index cebc7cea7f1ae90297ebf0802318099fb0498d4b..29ed1a98edfe8affd00433f4be6c1f850a4c0493 100644 (file)
@@ -168,7 +168,7 @@ void ia64_do_page_fault(unsigned long address, unsigned long isr,
        unsigned long is_data = !((isr >> IA64_ISR_X_BIT) & 1UL);
        IA64FAULT fault;
        int is_ptc_l_needed = 0;
-       u64 logps;
+       ia64_itir_t _itir = {.itir = itir};
 
        if ((isr & IA64_ISR_SP)
            || ((isr & IA64_ISR_NA)
@@ -190,14 +190,14 @@ void ia64_do_page_fault(unsigned long address, unsigned long isr,
                struct p2m_entry entry;
                unsigned long m_pteval;
                m_pteval = translate_domain_pte(pteval, address, itir,
-                                               &logps, &entry);
+                                               &(_itir.itir), &entry);
                vcpu_itc_no_srlz(current, is_data ? 2 : 1, address,
-                                m_pteval, pteval, logps, &entry);
+                                m_pteval, pteval, _itir.itir, &entry);
                if ((fault == IA64_USE_TLB && !current->arch.dtlb.pte.p) ||
                    p2m_entry_retry(&entry)) {
                        /* dtlb has been purged in-between.  This dtlb was
                           matching.  Undo the work.  */
-                       vcpu_flush_tlb_vhpt_range(address, logps);
+                       vcpu_flush_tlb_vhpt_range(address, _itir.ps);
 
                        // the stale entry which we inserted above
                        // may remains in tlb cache.
@@ -209,7 +209,7 @@ void ia64_do_page_fault(unsigned long address, unsigned long isr,
        }
 
        if (is_ptc_l_needed)
-               vcpu_ptc_l(current, address, logps);
+               vcpu_ptc_l(current, address, _itir.ps);
        if (!guest_mode(regs)) {
                /* The fault occurs inside Xen.  */
                if (!ia64_done_with_exception(regs)) {
index b35e52efea9608f5c927e651d98501bbf42f4f67..c5497d836d4f7e4894e8ce06d818d0f2b280d963 100644 (file)
@@ -448,11 +448,11 @@ gmfn_to_mfn_foreign(struct domain *d, unsigned long gpfn)
 // address, convert the pte for a physical address for (possibly different)
 // Xen PAGE_SIZE and return modified pte.  (NOTE: TLB insert should use
 // PAGE_SIZE!)
-u64 translate_domain_pte(u64 pteval, u64 address, u64 itir__, u64* logps,
+u64 translate_domain_pte(u64 pteval, u64 address, u64 itir__, u64* itir,
                          struct p2m_entry* entry)
 {
        struct domain *d = current->domain;
-       ia64_itir_t itir = {.itir = itir__};
+       ia64_itir_t _itir = {.itir = itir__};
        u64 mask, mpaddr, pteval2;
        u64 arflags;
        u64 arflags2;
@@ -461,13 +461,14 @@ u64 translate_domain_pte(u64 pteval, u64 address, u64 itir__, u64* logps,
        pteval &= ((1UL << 53) - 1);// ignore [63:53] bits
 
        // FIXME address had better be pre-validated on insert
-       mask = ~itir_mask(itir.itir);
+       mask = ~itir_mask(_itir.itir);
        mpaddr = ((pteval & _PAGE_PPN_MASK) & ~mask) | (address & mask);
 
-       if (itir.ps > PAGE_SHIFT)
-               itir.ps = PAGE_SHIFT;
+       if (_itir.ps > PAGE_SHIFT)
+               _itir.ps = PAGE_SHIFT;
 
-       *logps = itir.ps;
+       ((ia64_itir_t*)itir)->itir = _itir.itir;/* Copy the whole register. */
+       ((ia64_itir_t*)itir)->ps = _itir.ps;    /* Overwrite ps part! */
 
        pteval2 = lookup_domain_mpa(d, mpaddr, entry);
 
index f3e1a4b3493e0e25cee6f8e05d063d9db9276cdd..7cb22a3a8ed083da87b17a4cec2ee4e6c7dcce6a 100644 (file)
@@ -2200,23 +2200,25 @@ IA64FAULT vcpu_set_dtr(VCPU * vcpu, u64 slot, u64 pte,
 
 void
 vcpu_itc_no_srlz(VCPU * vcpu, u64 IorD, u64 vaddr, u64 pte,
-                 u64 mp_pte, u64 logps, struct p2m_entry *entry)
+                 u64 mp_pte, u64 itir, struct p2m_entry *entry)
 {
+       ia64_itir_t _itir = {.itir = itir};
        unsigned long psr;
-       unsigned long ps = (vcpu->domain == dom0) ? logps : PAGE_SHIFT;
+       unsigned long ps = (vcpu->domain == dom0) ? _itir.ps : PAGE_SHIFT;
 
-       check_xen_space_overlap("itc", vaddr, 1UL << logps);
+       check_xen_space_overlap("itc", vaddr, 1UL << _itir.ps);
 
        // FIXME, must be inlined or potential for nested fault here!
-       if ((vcpu->domain == dom0) && (logps < PAGE_SHIFT))
+       if ((vcpu->domain == dom0) && (_itir.ps < PAGE_SHIFT))
                panic_domain(NULL, "vcpu_itc_no_srlz: domain trying to use "
                             "smaller page size!\n");
 
-       BUG_ON(logps > PAGE_SHIFT);
+       BUG_ON(_itir.ps > PAGE_SHIFT);
        vcpu_tlb_track_insert_or_dirty(vcpu, vaddr, entry);
        psr = ia64_clear_ic();
        pte &= ~(_PAGE_RV2 | _PAGE_RV1);        // Mask out the reserved bits.
-       ia64_itc(IorD, vaddr, pte, ps); // FIXME: look for bigger mappings
+                                       // FIXME: look for bigger mappings
+       ia64_itc(IorD, vaddr, pte, IA64_ITIR_PS_KEY(ps, _itir.key));
        ia64_set_psr(psr);
        // ia64_srlz_i(); // no srls req'd, will rfi later
        if (vcpu->domain == dom0 && ((vaddr >> 61) == 7)) {
@@ -2224,39 +2226,42 @@ vcpu_itc_no_srlz(VCPU * vcpu, u64 IorD, u64 vaddr, u64 pte,
                // addresses never get flushed.  More work needed if this
                // ever happens.
 //printk("vhpt_insert(%p,%p,%p)\n",vaddr,pte,1L<<logps);
-               if (logps > PAGE_SHIFT)
-                       vhpt_multiple_insert(vaddr, pte, logps);
+               if (_itir.ps > PAGE_SHIFT)
+                       vhpt_multiple_insert(vaddr, pte, _itir.itir);
                else
-                       vhpt_insert(vaddr, pte, logps << 2);
+                       vhpt_insert(vaddr, pte, _itir.itir);
        }
        // even if domain pagesize is larger than PAGE_SIZE, just put
        // PAGE_SIZE mapping in the vhpt for now, else purging is complicated
-       else
-               vhpt_insert(vaddr, pte, PAGE_SHIFT << 2);
+       else {
+               _itir.ps = PAGE_SHIFT;
+               vhpt_insert(vaddr, pte, _itir.itir);
+       }
 }
 
 IA64FAULT vcpu_itc_d(VCPU * vcpu, u64 pte, u64 itir, u64 ifa)
 {
-       unsigned long pteval, logps = itir_ps(itir);
+       unsigned long pteval;
        BOOLEAN swap_rr0 = (!(ifa >> 61) && PSCB(vcpu, metaphysical_mode));
        struct p2m_entry entry;
+       ia64_itir_t _itir = {.itir = itir};
 
-       if (logps < PAGE_SHIFT)
+       if (_itir.ps < PAGE_SHIFT)
                panic_domain(NULL, "vcpu_itc_d: domain trying to use "
                             "smaller page size!\n");
 
  again:
        //itir = (itir & ~0xfc) | (PAGE_SHIFT<<2); // ignore domain's pagesize
-       pteval = translate_domain_pte(pte, ifa, itir, &logps, &entry);
+       pteval = translate_domain_pte(pte, ifa, itir, &(_itir.itir), &entry);
        if (!pteval)
                return IA64_ILLOP_FAULT;
        if (swap_rr0)
                set_one_rr(0x0, PSCB(vcpu, rrs[0]));
-       vcpu_itc_no_srlz(vcpu, 2, ifa, pteval, pte, logps, &entry);
+       vcpu_itc_no_srlz(vcpu, 2, ifa, pteval, pte, _itir.itir, &entry);
        if (swap_rr0)
                set_metaphysical_rr0();
        if (p2m_entry_retry(&entry)) {
-               vcpu_flush_tlb_vhpt_range(ifa, logps);
+               vcpu_flush_tlb_vhpt_range(ifa, _itir.ps);
                goto again;
        }
        vcpu_set_tr_entry(&PSCBX(vcpu, dtlb), pte, itir, ifa);
@@ -2265,25 +2270,26 @@ IA64FAULT vcpu_itc_d(VCPU * vcpu, u64 pte, u64 itir, u64 ifa)
 
 IA64FAULT vcpu_itc_i(VCPU * vcpu, u64 pte, u64 itir, u64 ifa)
 {
-       unsigned long pteval, logps = itir_ps(itir);
+       unsigned long pteval;
        BOOLEAN swap_rr0 = (!(ifa >> 61) && PSCB(vcpu, metaphysical_mode));
        struct p2m_entry entry;
+       ia64_itir_t _itir = {.itir = itir};
 
-       if (logps < PAGE_SHIFT)
+       if (_itir.ps < PAGE_SHIFT)
                panic_domain(NULL, "vcpu_itc_i: domain trying to use "
                             "smaller page size!\n");
       again:
        //itir = (itir & ~0xfc) | (PAGE_SHIFT<<2); // ignore domain's pagesize
-       pteval = translate_domain_pte(pte, ifa, itir, &logps, &entry);
+       pteval = translate_domain_pte(pte, ifa, itir, &(_itir.itir), &entry);
        if (!pteval)
                return IA64_ILLOP_FAULT;
        if (swap_rr0)
                set_one_rr(0x0, PSCB(vcpu, rrs[0]));
-       vcpu_itc_no_srlz(vcpu, 1, ifa, pteval, pte, logps, &entry);
+       vcpu_itc_no_srlz(vcpu, 1, ifa, pteval, pte, _itir.itir, &entry);
        if (swap_rr0)
                set_metaphysical_rr0();
        if (p2m_entry_retry(&entry)) {
-               vcpu_flush_tlb_vhpt_range(ifa, logps);
+               vcpu_flush_tlb_vhpt_range(ifa, _itir.ps);
                goto again;
        }
        vcpu_set_tr_entry(&PSCBX(vcpu, itlb), pte, itir, ifa);
index 28df5ff9beab108242e465c51f367dfcc94c02d9..afe1e355bc08124172471602f57750f13e9aeea2 100644 (file)
@@ -71,7 +71,7 @@ vhpt_erase(unsigned long vhpt_maddr)
        // initialize cache too???
 }
 
-void vhpt_insert (unsigned long vadr, unsigned long pte, unsigned long logps)
+void vhpt_insert (unsigned long vadr, unsigned long pte, unsigned long itir)
 {
        struct vhpt_lf_entry *vlfe = (struct vhpt_lf_entry *)ia64_thash(vadr);
        unsigned long tag = ia64_ttag (vadr);
@@ -80,21 +80,23 @@ void vhpt_insert (unsigned long vadr, unsigned long pte, unsigned long logps)
         * because the processor may support speculative VHPT walk.  */
        vlfe->ti_tag = INVALID_TI_TAG;
        wmb();
-       vlfe->itir = logps;
+       vlfe->itir = itir;
        vlfe->page_flags = pte | _PAGE_P;
        *(volatile unsigned long*)&vlfe->ti_tag = tag;
 }
 
-void vhpt_multiple_insert(unsigned long vaddr, unsigned long pte, unsigned long logps)
+void vhpt_multiple_insert(unsigned long vaddr, unsigned long pte,
+                          unsigned long itir)
 {
-       unsigned long mask = (1L << logps) - 1;
+       ia64_itir_t _itir = {.itir = itir};
+       unsigned long mask = (1L << _itir.ps) - 1;
        int i;
 
-       if (logps-PAGE_SHIFT > 10 && !running_on_sim) {
+       if (_itir.ps-PAGE_SHIFT > 10 && !running_on_sim) {
                // if this happens, we may want to revisit this algorithm
                panic("vhpt_multiple_insert:logps-PAGE_SHIFT>10,spinning..\n");
        }
-       if (logps-PAGE_SHIFT > 2) {
+       if (_itir.ps-PAGE_SHIFT > 2) {
                // FIXME: Should add counter here to see how often this
                //  happens (e.g. for 16MB pages!) and determine if it
                //  is a performance problem.  On a quick look, it takes
@@ -109,8 +111,8 @@ void vhpt_multiple_insert(unsigned long vaddr, unsigned long pte, unsigned long
        }
        vaddr &= ~mask;
        pte = ((pte & _PFN_MASK) & ~mask) | (pte & ~_PFN_MASK);
-       for (i = 1L << (logps-PAGE_SHIFT); i > 0; i--) {
-               vhpt_insert(vaddr,pte,logps<<2);
+       for (i = 1L << (_itir.ps-PAGE_SHIFT); i > 0; i--) {
+               vhpt_insert(vaddr, pte, _itir.itir);
                vaddr += PAGE_SIZE;
        }
 }
index 4a1e07077a7f29143376bc04899259ac688db45c..a436fedc960daba1c9b2b70ba7b519a6f76cbcce 100644 (file)
@@ -533,6 +533,20 @@ ia64_itr (__u64 target_mask, __u64 tr_num,
  * Insert a translation into the instruction and/or data translation
  * cache.
  */
+#ifdef XEN
+static inline void
+ia64_itc (__u64 target_mask, __u64 vmaddr, __u64 pte, __u64 itir)
+{
+       ia64_setreg(_IA64_REG_CR_ITIR, itir);
+       ia64_setreg(_IA64_REG_CR_IFA, vmaddr);
+       ia64_stop();
+       /* as per EAS2.6, itc must be the last instruction in an instruction group */
+       if (target_mask & 0x1)
+               ia64_itci(pte);
+       if (target_mask & 0x2)
+               ia64_itcd(pte);
+}
+#else
 static inline void
 ia64_itc (__u64 target_mask, __u64 vmaddr, __u64 pte,
          __u64 log_page_size)
@@ -546,6 +560,7 @@ ia64_itc (__u64 target_mask, __u64 vmaddr, __u64 pte,
        if (target_mask & 0x2)
                ia64_itcd(pte);
 }
+#endif
 
 /*
  * Purge a range of addresses from instruction and/or data translation
index e3636db2f4cebbfc790b2804127e411df5dae93e..e596db74f78ed57dc448ff8e19dffd4cc40c9782 100644 (file)
@@ -447,7 +447,8 @@ extern unsigned long dom0vp_expose_p2m(struct domain* d, unsigned long conv_star
 
 extern volatile unsigned long *mpt_table;
 extern unsigned long gmfn_to_mfn_foreign(struct domain *d, unsigned long gpfn);
-extern u64 translate_domain_pte(u64 pteval, u64 address, u64 itir__, u64* logps, struct p2m_entry* entry);
+extern u64 translate_domain_pte(u64 pteval, u64 address, u64 itir__,
+                               u64* itir, struct p2m_entry* entry);
 #define machine_to_phys_mapping        mpt_table
 
 #define INVALID_M2P_ENTRY        (~0UL)
index 351c1d701af65782b53bbe8d3e7aa54fc9270288..b0c988a32230b9dffe5e2de4eeed67ec1ed0bb3b 100644 (file)
@@ -38,9 +38,9 @@ struct vhpt_lf_entry {
 extern void vhpt_init (void);
 extern void gather_vhpt_stats(void);
 extern void vhpt_multiple_insert(unsigned long vaddr, unsigned long pte,
-                                unsigned long logps);
+                                unsigned long itir);
 extern void vhpt_insert (unsigned long vadr, unsigned long pte,
-                        unsigned long logps);
+                        unsigned long itir);
 void local_vhpt_flush(void);
 extern void vcpu_vhpt_flush(struct vcpu* v);